package components

import (
	"sync"
)

type Hub struct {
	//registered clients
	clients map[*Client]bool

	//inbound messages from the clients
	broadcast chan []byte
	// register requests from the clients
	register chan *Client
	// unregister requests from clients
	unregister chan *Client

	barrage chan []byte

	mu sync.Mutex
}

func NewHub() *Hub {
	return &Hub{
		broadcast:  make(chan []byte),
		register:   make(chan *Client),
		unregister: make(chan *Client),
		clients:    make(map[*Client]bool),
		barrage:    make(chan []byte),
	}
}

//生产消息
func (h *Hub) Produce(msg []byte) bool {
	h.barrage <- msg
	return true
}

func (h *Hub) Consume() {
	for {
		select {
		case message := <-h.barrage:
			h.broadcast <- message
		}
	}
}

func (h *Hub) Run() {
	for {
		select {
		case client := <-h.register:
			h.clients[client] = true
		case client := <-h.unregister:
			if _, ok := h.clients[client]; ok {
				delete(h.clients, client)
				close(client.send)
			}
		case message := <-h.broadcast:
			for client := range h.clients {
				select {
				case client.send <- message:
				default:
					close(client.send)
					delete(h.clients, client)
				}
			}

		}
	}
}
